package com.weilele.mvvm.adapter

import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import com.weilele.mvvm.utils.safeGet


abstract class MvvmHolder<DataType, Binding : ViewBinding?> : RecyclerView.ViewHolder {
    /**
     * viewBinding
     */
    private var _binding: Binding? = null
    val mBinding: Binding
        get() = _binding ?: throw IllegalArgumentException("binding is null")

    /**
     * 创建viewHolder的时候赋值的ViewGroup
     */
    internal var parent: ViewGroup? = null
    val bindingParent
        get() = itemView.parent.safeGet<ViewGroup>() ?: parent

    /**
     * 相关联的适配器
     */
    val adapter
        get() = bindingAdapter

    /**
     * 相对于单个adapter
     * [getAdapterPosition]一般和[bindingPosition]想同
     */
    val bindingPosition
        get() = bindingAdapterPosition

    /**
     * 相对于整个列表
     * [getLayoutPosition]一般和[absolutePosition]想同
     */
    val absolutePosition
        get() = absoluteAdapterPosition

    /**
     * 通过adapter计算，当前的数据
     */
    val bindingData: DataType?
        get() = when (adapter) {
            is IMvvmAdapter<*> -> {
                adapter.safeGet<IMvvmAdapter<DataType>>()?.getItemData(bindingPosition)
            }
            else -> null
        }

    /**
     * 绑定数据时候的对象
     */
    private var _currentBindData: DataType? = null
    val dataWhenBind: DataType?
        get() = _currentBindData

    /**
     * 绑定数据时候的位置，当发生了移除或者新增，
     * 并且数据没有改变，这里的值和[getAdapterPosition]不同
     */
    private var _positionWhenBind: Int? = null

    val positionWhenBind: Int?
        get() = _positionWhenBind

    /**
     * 这个注解主要是方便反射创建view
     */
    constructor(binding: Binding)
            : this(binding!!.root) {
        _binding = binding
    }

    /**
     * 主构造函数
     */
    constructor(itemView: View) : super(itemView)

    /**
     * 绑定数据
     */
    internal fun onBindData(position: Int, data: DataType, payloads: MutableList<Any>?) {
        _positionWhenBind = position
        _currentBindData = data
        bindData(data, payloads)
    }

    /**
     * 绑定数据
     */
    open fun bindData(data: DataType, payloads: MutableList<Any>?) {
        bindData(data)
    }

    abstract fun bindData(data: DataType)

    /**
     * view 附加到 窗口
     */
    open fun onViewAttachedToWindow() {

    }

    /**
     * view 从窗口移除
     */
    open fun onViewDetachedFromWindow() {

    }

    /**
     * holder回收的时候被调用
     */
    open fun onViewRecycled() {

    }

    /**
     *  holder回收失败的时候被调用
     */
    open fun onFailedToRecycleView() {

    }
}

